package com.cdplife.ci.modular.system.service.impl;

import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.cdplife.ci.core.common.exception.BizExceptionEnum;
import com.cdplife.ci.core.shiro.ShiroKit;
import com.cdplife.ci.core.util.StringUtil;
import com.cdplife.ci.modular.system.model.InsuranceKind;
import com.cdplife.ci.modular.system.model.PlanInsuranceKind;
import com.cdplife.ci.modular.system.model.Policy;
import com.cdplife.ci.modular.system.dao.PolicyMapper;
import com.cdplife.ci.modular.system.model.PolicyPlan;
import com.cdplife.ci.modular.system.service.IInsuranceKindService;
import com.cdplife.ci.modular.system.service.IPolicyPlanService;
import com.cdplife.ci.modular.system.service.IPolicyService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cdplife.ci.modular.system.service.impl.PolicyPlanServiceImpl.SUCCESS_TIP;

/**
 * <p>
 * 保单合同表 服务实现类
 * </p>
 *
 * @author jers
 * @since 2018-11-07
 */
@Service
public class PolicyServiceImpl extends ServiceImpl<PolicyMapper, Policy> implements IPolicyService {

    @Autowired
    private IInsuranceKindService insuranceKindService;

    @Autowired
    private IPolicyPlanService policyPlanService;

    @Override
    public List<Map<String, Object>> getPolicyList(Page<Policy> page, String policyCode, Integer policyStauts, String orderByField, boolean asc) {
        return this.baseMapper.getPolicyList(page, policyCode, policyStauts, orderByField, asc);
    }
    /**
     * 保单续签
     */
    @Override
    @Transactional
    public Object reNew(Policy policy){
        try {
            //校验空字符
            if (ToolUtil.isOneEmpty(policy.getInsuranceId(), policy.getPolicyCode(), policy.getEffectiveDate(),policy.getInvalidDate())) {
                throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
            }
            //保存保单基础信息
            Policy policyOld = this.selectById(policy.getId());
            policyOld.setLastModifiedBy(ShiroKit.getUser().getId().toString());
            policyOld.setCreatedBy(ShiroKit.getUser().getId().toString());
            policyOld.setInsuranceId(policy.getInsuranceId());
            policyOld.setPolicyCode(policy.getPolicyCode());
            policyOld.setEffectiveDate(policy.getEffectiveDate());
            policyOld.setInvalidDate(policy.getInvalidDate());
            policyOld.setInvalidDate(policy.getInvalidDate());
            policyOld.insert();
            //保存附件信息 未完
            //to do
            //新的保单ID
            Integer newPolicyId = policyOld.getId();
            //险种信息

            Wrapper<InsuranceKind> wrapper = new EntityWrapper<InsuranceKind>();
            wrapper = wrapper.eq("policy_id", policy.getId()).and().eq("is_del",0);
            List<InsuranceKind> insuranceKinds = insuranceKindService.selectList(wrapper);
            //新旧险种ID集合
            Map<Integer,Integer> insuranceKindIdMap = new HashMap<>();
            for(InsuranceKind insuranceKind : insuranceKinds){
                int oldInsuranceKindId = insuranceKind.getId();
                insuranceKind.setLastModifiedBy(ShiroKit.getUser().getId().toString());
                insuranceKind.setCreatedBy(ShiroKit.getUser().getId().toString());
                insuranceKind.setPolicyId(newPolicyId);
                insuranceKind.insert();
                insuranceKindIdMap.put(oldInsuranceKindId,insuranceKind.getId());
            }
            //保存保障计划，计划险种
            Map<Integer, Object> data = policyPlanService.getPolicyPlanListByPolicyId(policy.getId());
            for(Object obj : data.values()){
                HashMap<String,Object> PolicyPlanInfo = (HashMap<String,Object>)obj;
                PolicyPlan policyPlan = (PolicyPlan)PolicyPlanInfo.get("policyPlan");
                List<Map<String, Object>> planInsuranceKinds = (List<Map<String, Object>>)PolicyPlanInfo.get("planInsuranceKinds");
                //增加保障计划
                policyPlan.setLastModifiedBy(ShiroKit.getUser().getId().toString());
                policyPlan.setCreatedBy(ShiroKit.getUser().getId().toString());
                policyPlan.setPolicyId(newPolicyId);
                policyPlan.insert();
                //新的保障计划ID
                int newPolicyPlanId = policyPlan.getId();
                //增加计划险种信息
                for(Map<String, Object> planInsuranceKindTmp : planInsuranceKinds){
                    PlanInsuranceKind planInsuranceKind = new PlanInsuranceKind();
                    Long oldInsuranceKindIdTmp = (Long)planInsuranceKindTmp.get("id");
                    int oldInsuranceKindId = oldInsuranceKindIdTmp.intValue();
                    int newInsuranceKindId = insuranceKindIdMap.get(oldInsuranceKindId);
                    planInsuranceKind.setLastModifiedBy(ShiroKit.getUser().getId().toString());
                    planInsuranceKind.setPlanId(newPolicyPlanId);
                    planInsuranceKind.setInsuranceKindId(newInsuranceKindId);
                    planInsuranceKind.setAmountType((Integer) planInsuranceKindTmp.get("amount_type"));
                    planInsuranceKind.setAmountLimit((BigDecimal)planInsuranceKindTmp.get("amount_limit"));
                    planInsuranceKind.setAmount((BigDecimal)planInsuranceKindTmp.get("amount"));
                    planInsuranceKind.setSalaryTimes((Integer) planInsuranceKindTmp.get("salary_times"));
                    planInsuranceKind.insert();
                }
            }
            //存在关联的客户员工方案 未完
            //.....
            //设置当前用户
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        return SUCCESS_TIP;
    }

    /**
     * 保单删除
     */
    public Object deletePolicy(Integer policyId){
        if(policyId == 0){
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        try{
            //存在关联的客户员工方案 未完 以及删除逻辑
            Policy policy = this.baseMapper.selectById(policyId);
            policy.setLastModifiedBy(ShiroKit.getUser().getId().toString());
            policy.setIsDel(1);
            this.baseMapper.updateById(policy);
            return SUCCESS_TIP;
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
    }
    /**
     * 保单增加
     */
    public Object addPolicy(Policy policy){
        if(policy == null){
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        //校验空字符
        if (ToolUtil.isOneEmpty(policy.getInsuranceId(), policy.getPolicyCode(), policy.getEffectiveDate(),policy.getInvalidDate())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        try{
            //校验重复保险公司ID与保单CODE
            Wrapper<Policy> wrapper = new EntityWrapper<Policy>();
            wrapper = wrapper.eq("insurance_id", policy.getInsuranceId()).and().eq("policy_code",policy.getPolicyCode()).and().eq("is_del",0);
            List<Policy> policies = this.baseMapper.selectList(wrapper);
            if (policies == null || policies.size() == 0) {
                //设置当前用户
                if(policy.getPolicyType() == 1){
                    policy.setTenantId(0);
                }
                policy.setCreatedBy(ShiroKit.getUser().getId().toString());
                policy.insert();
                return SUCCESS_TIP;
            }else{
                throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
    }
    /**
     * 保单修改
     */
    public Object updatePolicy(Policy policy){
        if(policy == null){
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        //校验空字符
        if (ToolUtil.isOneEmpty(policy.getInsuranceId(), policy.getPolicyCode(), policy.getEffectiveDate(),policy.getInvalidDate())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        try{
            //存在关联的客户员工方案 未完
            //.....
            //设置当前用户
            if(policy.getPolicyType() == 1){
                policy.setTenantId(0);
            }
            policy.setLastModifiedBy(ShiroKit.getUser().getId().toString());
            policy.updateById();
            return SUCCESS_TIP;
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
    }
    /**
     * 保单修改
     */
    public Object updateContacts(Policy policy){
        if(policy == null){
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        //校验空字符
        if (ToolUtil.isOneEmpty(policy.getId(),policy.getLinkman(), policy.getTel(), policy.getEmail(),policy.getMobile())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        try{
            //设置当前用户
            policy.setLastModifiedBy(ShiroKit.getUser().getId().toString());
            policy.updateById();
            return SUCCESS_TIP;
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
    }


    /**
     * 定时任务：变更保单状态
     */
    @Transactional
    public void changePolicyStatus(){
        //获取当前保单
        Wrapper<Policy> wrapper = new EntityWrapper<Policy>();
        wrapper = wrapper.eq("is_del",0);
        List<Policy> policies = this.baseMapper.selectList(wrapper);
        for (Policy policy : policies){
            //判断当天是否在生效与失效期间
            int status = StringUtil.belongCalendar(new Date(),policy.getEffectiveDate(),policy.getInvalidDate());
            if(status > 0 ){
                policy.setPolicyStauts(3);
            }else if(status == 0){
                policy.setPolicyStauts(2);
            }else if(status < 0){
                policy.setPolicyStauts(1);
            }
            policy.updateById();
        }
    }
}
